import Draw from 'ol/interaction/Draw';
import VectorLayer from 'ol/layer/Vector';
import Point from 'ol/geom/Point';
import { unByKey } from 'ol/Observable';
import Overlay from 'ol/Overlay';
import { Feature } from 'ol';
import { getArea, getLength } from 'ol/sphere';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
 
export default {
    measure(map, measureType, show,source) {
        //let source = new VectorSource(); // 创建一个新的矢量源
 
        let sketch; // 当前绘制的要素
 
        let helpTooltipElement; // 帮助提示元素
 
        let helpTooltip; // 显示帮助消息的覆盖层
 
        let measureTooltipElement; // 测量提示元素
 
        let measureTooltip; // 显示测量结果的覆盖层
 
        const continuePolygonMsg = ''; // 绘制多边形时显示的消息
 
        const continueLineMsg = ''; // 绘制线条时显示的消息
 
        createMeasureTooltip(); // 创建测量提示
        createHelpTooltip(); // 创建帮助提示
 
        const pointerMoveHandler = function (evt) {
            if (evt.dragging) {
                return;
            }
            let helpMsg = '请点击开始绘制'; // 默认帮助消息
            if (sketch) {
                const geom = sketch.getGeometry();
                if (geom instanceof Polygon) {
                    helpMsg = continuePolygonMsg; // 如果是多边形，显示相应消息
                } else if (geom instanceof LineString) {
                    helpMsg = continueLineMsg; // 如果是线条，显示相应消息
                }
            }
 
            helpTooltipElement.innerHTML = helpMsg; // 更新帮助提示内容
            helpTooltip.setPosition(evt.coordinate); // 设置帮助提示位置
 
            helpTooltipElement.classList.remove('hidden'); // 显示帮助提示
        };
 
        map.on('pointermove', pointerMoveHandler); // 监听指针移动事件
 
        map.getViewport().addEventListener('mouseout', function () {
            helpTooltipElement.classList.add('hidden'); // 鼠标移出视口时隐藏帮助提示
        });
 
        let draw; // 绘制交互
 
        const formatLength = function (line) {
            const sourceProj = map.getView().getProjection(); // 获取投影坐标系
            const length = getLength(line, { projection: sourceProj }); // 计算长度
            let output;
            if (length > 100) {
                output = (Math.round(length / 1000 * 100) / 100) + ' km'; // 如果长度大于100米，显示为公里
            } else {
                output = (Math.round(length * 100) / 100) + ' m'; // 否则显示为米
            }
            return output;
        };
 
       
 
        for (const layerTmp of map.getLayers().getArray()) {
            if (layerTmp.get('name') == 'feature') {
                source = layerTmp.getSource(); // 获取存放要素的矢量层
            }
        }
 
        function addInteraction() {
            const type = (measureType == 'area' ? 'Polygon' : 'LineString'); // 根据测量类型设置绘制类型
            draw = new Draw({
                source: source,
                type: type,
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)', // 填充颜色
                    }),
                    stroke: new Stroke({
                        color: 'rgba(255, 0, 0, 0.5)', // 线条颜色
                        lineDash: [10, 10], // 虚线样式
                        width: 2, // 线条宽度
                    }),
                    image: new CircleStyle({
                        radius: 5, // 圆点半径
                        stroke: new Stroke({
                            color: 'rgba(0, 0, 0, 0.7)', // 圆点边框颜色
                        }),
                        fill: new Fill({
                            color: 'rgba(255, 255, 255, 0.2)', // 圆点填充颜色
                        }),
                    }),
                }),
            });
            map.addInteraction(draw); // 添加绘制交互
            
            let listener;
            draw.on('drawstart', function (evt) {
                sketch = evt.feature; // 设置当前绘制的要素
 
                let tooltipCoord = evt.coordinate; // 提示坐标
 
                listener = sketch.getGeometry().on('change', function (evt) {
                    const geom = evt.target;
                    let output;
                    if (geom instanceof Polygon) {
                        output = formatArea(map,geom); // 格式化面积
                        tooltipCoord = geom.getInteriorPoint().getCoordinates(); // 获取多边形内部点坐标
                    } else if (geom instanceof LineString) {
                        output = formatLength(geom); // 格式化长度
                        tooltipCoord = geom.getLastCoordinate(); // 获取线条最后一个点的坐���
                    }
                    measureTooltipElement.innerHTML = output; // 更新测量提示内容
                    measureTooltip.setPosition(tooltipCoord); // 设置测量提示位置
                });
 
                map.on('dblclick', function (evt) {
                    const point = new Point(evt.coordinate);
                    source.addFeature(new Feature(point)); // 添加双击点要素
                });
            });
 
            draw.on('drawend', function () {
                measureTooltipElement.className = 'tooltip tooltip-static'; // 设置测量提示样式
                measureTooltip.setOffset([0, -7]); // 设置测量提示偏移
                sketch = null; // 清空当前绘制的要素
                measureTooltipElement = null; // 清空测量提示元素
                createMeasureTooltip(); // 创建新的测量提示
                unByKey(listener); // 移除监听器
                map.un('pointermove', pointerMoveHandler); // 移除指针移动事件监听
                map.removeInteraction(draw); // 移除绘制交互
                helpTooltipElement.classList.add('hidden'); // 隐藏帮助提示
            });
        }
 
        function createHelpTooltip() {
            if (helpTooltipElement) {
                helpTooltipElement.parentNode.removeChild(helpTooltipElement); // 移除旧的帮助提示元素
            }
            helpTooltipElement = document.createElement('div');
            helpTooltipElement.className = 'tooltip hidden'; // 设置帮助提示样式
            helpTooltip = new Overlay({
                element: helpTooltipElement,
                offset: [15, 0], // 设置偏移
                positioning: 'center-left', // 设置定位方式
            });
            map.addOverlay(helpTooltip); // 添加帮助提示覆盖层
        }
 
        function createMeasureTooltip() {
            if (measureTooltipElement) {
                measureTooltipElement.parentNode.removeChild(measureTooltipElement); // 移除旧的测量提示元素
            }
            measureTooltipElement = document.createElement('div');
            measureTooltipElement.className = 'tooltip tooltip-measure'; // 设置测量提示样式
            measureTooltip = new Overlay({
                element: measureTooltipElement,
                offset: [0, -15], // 设置偏移
                positioning: 'bottom-center', // 设置定位方式
            });
            map.addOverlay(measureTooltip); // 添加测量提示覆盖层
        }
 
        addInteraction(); // 添加绘制交互
 
        const vector = new VectorLayer({
            name: 'lineAndArea',
            source: source,
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)', // 填充颜色
                }),
                stroke: new Stroke({
                    color: 'red', // 线条颜色
                    width: 2, // 线条宽度
                }),
                image: new CircleStyle({
                    radius: 7, // 圆点半径
                    fill: new Fill({
                        color: '#ffcc33', // 圆点填充颜色
                    }),
                }),
            }),
            zIndex: 16, // 设置图层顺序
        });
 
        if (show && measureType) {
            map.addLayer(vector); // 显示测量图层
        } else {
            map.getOverlays().clear(); // 清除所有覆盖层
 
            map.getLayers().getArray().forEach((layer, index, array) => {
                if (layer.get('name') == 'lineAndArea') {
                    map.removeLayer(layer); // 移除测量图层
                }
            });
        }
    },
};

export const formatArea = function (map,polygon) {
    const sourceProj = map.getView().getProjection(); // 获取投影坐标系
    const area = getArea(polygon, { projection: sourceProj }); // 计算面积
    let output;
    if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) + ' km<sup>2</sup>'; // 如果面积大于10000平方米，显示为平方公里
    } else {
        output = (Math.round(area * 100) / 100) + ' m<sup>2</sup>'; // 否则显示为平方米
    }
    return output;
};